import axios from '@ohos/axios';
import protobuf from 'protobufjs';
import buffer from '@ohos.buffer';
import logger from '../core/logger';
import grpcResult from './model/grpcResult';
import { requestHeader } from './requestHeader';

export class request {
  async getMsg(pack: string, name: string, keyObj: any) {
    try {
      let ret = await protobuf.load(name);
      if (ret) {
        var msg = ret.lookupType(`${pack}.${name}`);
        let message = msg.create(keyObj);
        return msg.encode(message).finish();
      }
    } catch (e) {
      logger.error(e);
    }
    return null;
  }

  async sendMessage(url: string, messageBytes: Uint8Array, access_key: string = ""): Promise<grpcResult> {
    let ret = new grpcResult();
    try {
      const config = new requestHeader(access_key);
      let uaBuilder: string;
      uaBuilder += `Dalvik/${requestHeader.dalvik_ver} `;
      uaBuilder += `(Linux; U; Android ${requestHeader.os_ver}; ${requestHeader.brand} ${requestHeader.model}) ${requestHeader.app_ver} `;
      uaBuilder += `os/android model/${requestHeader.model} mobi_app/android build/${requestHeader.build} `;
      uaBuilder += `channel/${requestHeader.channel} innerVer/${requestHeader.build} osVer/${requestHeader.os_ver} `;
      uaBuilder += `network/${requestHeader.network_type}`;
      axios.defaults.headers.common['User-Agent'] = uaBuilder;
      axios.defaults.headers.common['APP-KEY'] = 'android';
      axios.defaults.headers.common['x-bili-metadata-bin'] = config.getMetadataBin();
      axios.defaults.headers.common['authorization'] = 'identify_v1 ' + access_key;
      axios.defaults.headers.common['x-bili-device-bin'] = config.getDeviceBin();
      axios.defaults.headers.common['x-bili-network-bin'] = config.getNetworkBin();
      axios.defaults.headers.common['x-bili-restriction-bin'] = '';
      axios.defaults.headers.common['x-bili-locale-bin'] = config.getLocaleBin();
      axios.defaults.headers.common['x-bili-fawkes-req-bin'] = config.getFawkesreqBin();
      axios.defaults.headers.common['grpc-accept-encoding'] = 'identity';
      axios.defaults.headers.common['grpc-timeout'] = '17985446u';
      axios.defaults.headers.common['env'] = 'prod';
      axios.defaults.headers.common['Transfer-Encoding'] = 'chunked';
      axios.defaults.headers.common['TE'] = 'trailers';
      const stateBytes = new Uint8Array([0, 0, 0, 0, messageBytes.length]);
      const bodyBytes = new Uint8Array(5 + messageBytes.length);
      bodyBytes.set(stateBytes, 0);
      bodyBytes.set(messageBytes, 5);
      const response = await axios.post(url, bodyBytes, {
        headers: {
          'Content-Type': 'application/grpc',
          'Content-Length': bodyBytes.length.toString()
        },
        responseType: 'arraybuffer'
      });
      const data = new Uint8Array(response.data);
      if (data.length > 5) {
        ret.code = 0;
        ret.status = true;
        ret.message = '请求成功';
        ret.results = data.slice(5);
      } else {
        ret.code = -102;
        ret.status = false;
        ret.message = '请求失败，没有数据返回';
      }
    } catch (ex) {
      ret.code = ex.code || ex.HResult;
      ret.status = false;
      ret.message = '发送gRPC请求失败' + ex.message;
    }
    return ret;
  }

  get(url: string): Promise<grpcResult> {
    return new Promise((resolve) => {
      let ret = new grpcResult();
      try {
        axios.get(url, {
          responseType: 'arraybuffer',
          headers: { 'Content-Type': 'application/grpc' }
        }).then((res) => {
          if (res.status == 200) {
            let arr = buffer.from(res.data);
            if (arr.length > 5) {
              ret.code = 0;
              ret.status = true;
              ret.message = `请求成功`;
              ret.results = arr.subarray(5).buffer;
            } else {
              ret.code = -102;
              ret.status = false;
              ret.message = `请求失败,没有数据返回`;
            }
          }
        });
      } catch (e) {
        logger.error(e);
        ret.code = -999;
        ret.status = false;
        ret.message = `发送http请求失败${e}`;
      }
      resolve(ret);
    });
  }
}
export default new request();